﻿using Microsoft.AspNetCore.Mvc;

using PLCS.Domain.Equipments;
using PLCS.Domain.Shared.Enums;
using PLCS.Domain.Shared.Equipments;
using PLCS.Domain.Tasks;
using PLCS.SocialHttpApi.Attributes;
using PLCS.SocialHttpApi.Models;

using System.ComponentModel;

using Volo.Abp.AspNetCore.Mvc;

namespace PLCS.SocialHttpApi.Controllers
{
    [Route("api/[controller]/[action]")]
    [ApiController]
    [ServiceFilter(typeof(LogActionFilter))]
    public class AGVController : AbpControllerBase
    {
        private readonly ITaskRepository _taskRepository;
        private readonly IInstructionRepository _instructionRepository;
        private readonly IEquipmentRepository _equipmentRepository;

        public AGVController(ITaskRepository taskRepository, IInstructionRepository instructionRepository, IEquipmentRepository equipmentRepository)
        {
            _taskRepository = taskRepository;
            _instructionRepository = instructionRepository;
            _equipmentRepository = equipmentRepository;
        }

        [HttpPost]
        [Description("AGV给PLCS反馈任务状态")]
        [Requester("AGV")]
        public async Task<Response_AGV> Agv_to_plcs_task_status(Request_AGV_task_Status request)
        {
            string seqNo = request.header.seqNo;
            string taskId = request.body.TaskId;
            int taskStatus = request.body.TaskStatus;
            var task = await _instructionRepository.FindAsync(x => x.InstructionNo.ToString() == taskId);
            if (task == null)
            {
                return new Response_AGV(new ResponseHeader("E", seqNo, "未找到任务"));
            }
            switch (taskStatus)
            {
                case 1:
                    //task.ChangeStatus(Domain.Shared.Enums.TaskStatus.执行中);
                    break;

                case 2:
                    task.ChangeStatus(Domain.Shared.Tasks.InstructionStatus.已完成);
                    await _instructionRepository.UpdateAsync(task);
                    break;

                default:
                    return new Response_AGV(new ResponseHeader("E", seqNo, "任务类型有误"));
            }
            return new Response_AGV(new ResponseHeader("S", seqNo, ""));
        }

        [HttpPost]
        [Description("AGV给PLCS反馈设备状态")]
        [Requester("AGV")]
        public async Task<Response_AGV> Agv_to_plcs_equipment_status(Request_AGV_Equipment_Status request)
        {
            string seqNo = request.header.seqNo;
            string equipmentNo = request.body.EquipmentNo;
            int onlineMode = request.body.OnlineMode;
            int status = request.body.Status;

            var equipment = await _equipmentRepository.GetByEquipmentNoAsync(equipmentNo);
            if (equipment == null)
            {
                return new Response_AGV(new ResponseHeader("E", seqNo, "设备不存在"));
            }

            equipment.OnlineStatus = (OnlineMode)Enum.Parse(typeof(OnlineMode), onlineMode.ToString());
            equipment.Status = (DeviceStatus)Enum.Parse(typeof(DeviceStatus), status.ToString());
            await _equipmentRepository.UpdateAsync(equipment);

            return new Response_AGV(new ResponseHeader("S", seqNo, ""));
        }

        [HttpPost]
        [Description("AGV给PLCS请求开关门")]
        [Requester("AGV")]
        public async Task<Response_AGV> agv_to_plcs_open_door(Request_AGV_Open_Door request)
        {
            string seqNo = request.header.seqNo;
            string equipmentNo = request.body.EquipmentNo; // 其实用不到，也可以做个校验。
            int type = request.body.Type; //1：开门，2：关门
            if (equipmentNo != "DZ1")
                return new Response_AGV(new ResponseHeader("E", seqNo, $"设备{equipmentNo}不在此区域作业"));
            if (type == 1)
            {
                // TODO:处理开门逻辑
                // 1.判断RGV是否在最下面的工位，如果在要移走
                // 2.读取PLC门开关的信号，如果关着，需要发信号开门
                // 3.满足RGV不在最下面且PLC开着的信号，则返回S
                // AGV会一直请求，因为在开门和移动RGV小车的过程中肯定是一直是E，直到两个信号满足，返回S
            }
            else if (type == 2)
            {
                // TODO:处理关门逻辑
                // 当AGV完全进来或者完全出去之后，会告诉我们，此时RGV车可以正常移动，同时发送PLC信号——关门
            }
            else
                return new Response_AGV(new ResponseHeader("E", seqNo, "类型错误"));

            return new Response_AGV(new ResponseHeader("S", seqNo, ""));
        }
    }
}